package com.yazi.mxz.common.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import com.myframework.smhj.common.exception.MyEntityNotExistsException;
import com.myframework.smhj.common.exception.MyException;
import com.myframework.smhj.common.exception.MyIllegalArgumentException;
import com.myframework.smhj.common.exception.MyNoPermissionException;
import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.dao.BasicService;
import com.myframework.smhj.hibernate.dao.Dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yazi.mxz.common.MyUtil;
import com.yazi.mxz.common.db.dao.AddressDao;
import com.yazi.mxz.common.db.dao.CategoryDao;
import com.yazi.mxz.common.db.dao.MemberDao;
import com.yazi.mxz.common.db.dao.MemberSpendDao;
import com.yazi.mxz.common.db.dao.MemberVipDao;
import com.yazi.mxz.common.db.dao.LocalSaleGoodsDao;
import com.yazi.mxz.common.db.dao.LocalSaleDao;
import com.yazi.mxz.common.db.dao.OrderDao;
import com.yazi.mxz.common.db.dao.OrderGoodsDao;
import com.yazi.mxz.common.db.dao.ShoppingCartDao;
import com.yazi.mxz.common.db.dao.ShoppingDao;
import com.yazi.mxz.common.db.dao.StoreDao;
import com.yazi.mxz.common.db.dao.StoreGoodsDao;
import com.yazi.mxz.common.db.dao.StoreMemberDao;
import com.yazi.mxz.common.db.dao.StorePromoteDao;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.Address;
import com.yazi.mxz.common.entity.beans.Category;
import com.yazi.mxz.common.entity.beans.Company;
import com.yazi.mxz.common.entity.beans.GoodsGift;
import com.yazi.mxz.common.entity.beans.Member;
import com.yazi.mxz.common.entity.beans.MemberSpend;
import com.yazi.mxz.common.entity.beans.MemberVip;
import com.yazi.mxz.common.entity.beans.MemberVipId;
import com.yazi.mxz.common.entity.beans.LocalSaleGoods;
import com.yazi.mxz.common.entity.beans.LocalSale;
import com.yazi.mxz.common.entity.beans.Order;
import com.yazi.mxz.common.entity.beans.OrderGoods;
import com.yazi.mxz.common.entity.beans.Shopping;
import com.yazi.mxz.common.entity.beans.Store;
import com.yazi.mxz.common.entity.beans.StoreGift;
import com.yazi.mxz.common.entity.beans.StoreGoods;
import com.yazi.mxz.common.entity.beans.StoreMember;
import com.yazi.mxz.common.entity.beans.StoreMemberId;
import com.yazi.mxz.common.entity.beans.StorePromote;
import com.yazi.mxz.common.entity.custom.LocalSaleGoods4Sync;
import com.yazi.mxz.common.entity.custom.LocalSale4Sync;
import com.yazi.mxz.common.entity.custom.LocalSales4Sync;
import com.yazi.mxz.common.entity.custom.Order4Form;
import com.yazi.mxz.common.entity.custom.Orders4Form;
import com.yazi.mxz.common.entity.enums.OrderGoodsType;
import com.yazi.mxz.common.entity.enums.OrderPayMethodType;
import com.yazi.mxz.common.entity.enums.OrderStatus;
import com.yazi.mxz.common.entity.enums.StoreGoodsStatus;
import com.yazi.mxz.common.entity.enums.StorePromoteStatus;
import com.yazi.mxz.common.entity.enums.StorePromoteType;
import com.yazi.mxz.common.exception.Code;
import com.yazi.mxz.common.exception.MxzStoreGoodsException;
import com.yazi.mxz.common.exception.MxzStorePromoteException;
import com.yazi.mxz.common.service.OrderService;


/**
 * 订单添加
 * @author mo_yq5
 * @date 2015-6-22
 */
public abstract class OrderServiceAddImpl extends BasicService<Order> implements OrderService {
	private static Logger log = LoggerFactory.getLogger(OrderServiceAddImpl.class);

	@Resource
	OrderDao orderDao;
	@Resource
	StoreDao storeDao;
	@Resource
	AddressDao addressDao;
	@Resource
	StoreGoodsDao storeGoodsDao;
	@Resource
	OrderGoodsDao orderGoodsDao;
	@Resource
	ShoppingDao shoppingDao;
	@Resource
	ShoppingCartDao shoppingCartDao;
	@Resource
	MemberDao memberDao;
	@Resource
	StoreMemberDao storeMemberDao;
	@Resource
	CategoryDao categoryDao;
	@Resource
	StorePromoteDao storePromoteDao;
	@Resource
	LocalSaleDao localSaleDao;
	@Resource
	LocalSaleGoodsDao localSaleGoodsDao;
	@Resource
	MemberVipDao memberVipDao;
	@Resource
	MemberSpendDao memberSpendDao;

	@Override
	protected Dao<Order> getDao() {
		return orderDao;
	}
	
	@Override
	public void addByMember(Member member, Orders4Form ordersObject) 
			throws MyException {
		log.debug("addByMember：memberId={}", member.getMemberId());
		
		// 店铺ID集合
		List<Long> storeIdList = new ArrayList<Long>();

		// 收货地址
		Long addressId = ordersObject.getAddressId();
		if (null == addressId) {
			throw new MyIllegalArgumentException("未指定收货地址");
		}
		Address address = addressDao.get(addressId);
		if (null == address) {
			throw new MyEntityNotExistsException("收货地址不存在");
		}
		
		// 表单订单
		List<Order4Form> orderFromFormList = ordersObject.getOrders();

		// 生成后台订单
		for (Order4Form orderFromForm : orderFromFormList) {
			
			Long storeId = null;
			
			// 订单参数完整性检查
			if (null == orderFromForm.getStore()
					|| null == (storeId = orderFromForm.getStore().getStoreId()) // 未指定订单店铺
					|| null == orderFromForm.getDeliveryId() // 未指定配送方式
					|| null == orderFromForm.getPayId() // 未指定支付方式
					|| null == orderFromForm.getShoppingIds()
					|| orderFromForm.getShoppingIds().length == 0 // 未指定买购的物品
			) {
				throw new MyIllegalArgumentException();
			}
			
			storeIdList.add(storeId);
			
			/**
			 * 店铺
			 */
			
			Store store = storeDao.get(storeId);
			// 指定的店铺不存在
			if (null == store) {
				throw new MyIllegalArgumentException();
			}

			/**
			 * 配送方式
			 */
			
			Category deliveryMethod = categoryDao.get(orderFromForm.getDeliveryId());
			// 配送方式不存在或者不属于指定店铺
			if (null == deliveryMethod // ||
										// !store.getExpresses().contains(express)
			) {
				throw new MyIllegalArgumentException();
			}
			
			/**
			 * 支付方式
			 */
			
			Category payType = categoryDao.get(orderFromForm.getPayId());
			// 支付方式不存在或者不属于指定店铺
			if (null == payType // || !store.getPayTypes().contains(payType)
			) {
				throw new MyIllegalArgumentException();
			}

			/**
			 * 目标订单
			 */
			
			// 订单
			Order newOrder = new Order();
			// 订单商品集合
			List<OrderGoods> nogList = new ArrayList<OrderGoods>();// newOrderGoodsList
			// 订单金额
			float totalCost = 0;
			
			// 物品
			Long[] shoppingIds = orderFromForm.getShoppingIds();
			for (Long shoppingId : shoppingIds) {
				
				/**
				 * 物品
				 */
				
				if (null == shoppingId) {
					throw new MyIllegalArgumentException();
				}
				
				Shopping shopping = shoppingDao.get(shoppingId);
				
				// 物品信息不存在
				if (null == shopping) {
					throw new MyEntityNotExistsException();
				}
				// 不是自己的物品
				if (shopping.getMemberId().longValue() != member.getMemberId()) {
					throw new MyNoPermissionException();
				}
				
				/**
				 * 店铺商品
				 */
				
				// 要现买的商品
				StoreGoods storeGoods = shopping.getStoreGoods();
				// 商品所在店铺与订单指定的店铺不一致
				if (storeGoods.getStore().getStoreId().longValue() != storeId) {
					throw new MyNoPermissionException();
				}
				// 商品已经下架
				if (storeGoods.getStatus().equals(StoreGoodsStatus.OFF.getValue())) {
					throw new MxzStoreGoodsException(Code.ERR_10001, storeGoods);
				}

				// 购买量
				float buyCount = shopping.getBuyCount();

				// 库存不足
				if (storeGoods.getStockConvert() < buyCount) {
					throw new MxzStoreGoodsException(Code.ERR_10002, storeGoods);
				}
				
				// 计费单位与出售单位是否相同
				boolean isSingleUnit = null == storeGoods.getSellUnit();
				// 价格
				float price = storeGoods.getPrice();
				// 转换成计费单位下的购买量
				float reckonCount = new Double(buyCount
						* (isSingleUnit ? 1 : storeGoods.getUnitConvert())).floatValue();
				// 转换成计费单位下商品小计
				float reckonCost = price * reckonCount;

				// 订单价格统计
				totalCost += reckonCost;
				
				/**
				 * 订单商品
				 */

				// 订单商品信息
				OrderGoods nog = new OrderGoods();// newOrderGoods
				nog.setBarCode(storeGoods.getBarCode());
				nog.setBuyCount(buyCount);
				nog.setBuyUnit(storeGoods.getSellUnit());
				nog.setChecked(isSingleUnit);
				nog.setGoodsTime(storeGoods.getUpdateTime());
				nog.setName(storeGoods.getName());
				nog.setOrder(newOrder);
				nog.setOrderTime(DateUtil.getTimeStamp());
				nog.setPic(storeGoods.getPic());
				nog.setPrice(price);
				nog.setRealCost(reckonCost);
				nog.setRealCount(reckonCount);
				nog.setReckonCost(reckonCost);
				nog.setReckonCount(reckonCount);
				nog.setStoreGoodsId(storeGoods.getStoreGoodsId());
				nog.setType(OrderGoodsType.SELL.ordinal());
				nog.setUnit(storeGoods.getUnit());
				nog.setUnitConvert(storeGoods.getUnitConvert());

				// 加入到订单商品列表中
				nogList.add(nog);
				// 记录出售量
				sale(storeGoods, reckonCount);
				
				/**
				 * 商品随赠品
				 */

				// 随赠促销中
				if (storeGoods.getAtGift()) {
					
					Iterator<GoodsGift> gifts = storeGoods.getGoodsGiftsForSellId().iterator();
					while (gifts.hasNext()) {
						
						GoodsGift gift = gifts.next();
						OrderGoods og = mkOrderGoodsForFree(gift.getStoreGoodsByGiftId(),
								gift.getAmount(), newOrder);
						
						// 加入到订单商品列表中
						if (null != og) {
							nogList.add(og);
						}
						
					}
					
				}
			}

			/**
			 * 订单促销
			 */
			
			// 订单促销
			StorePromote storePromote = new StorePromote();
			// 总共获得的满减金额
			float promoteBack = 0;
			
			if (null != orderFromForm.getPromoteId()) {
				
				storePromote = storePromoteDao.get(orderFromForm.getPromoteId());
				if (null == storePromote) {
					throw new MyEntityNotExistsException();
				}
				
				if (!storePromote.getStore().equals(store)) {
					throw new MyNoPermissionException();
				}
				// 促销不在进行
				if (storePromote.getStatus().intValue() != StorePromoteStatus.SALING.ordinal()) {
					throw new MxzStorePromoteException(Code.ERR_11000, storePromote);
				}

				// 满减
				if (storePromote.getType().intValue() == StorePromoteType.MINUS.ordinal()) {
					
					// 订单金额未满足满减要求
					if (totalCost < storePromote.getCost()) {
						throw new MxzStorePromoteException(Code.ERR_11000, storePromote);
					}
					
					promoteBack = storePromote.getBack();
					if (storePromote.getIsAnalogy()) {
						promoteBack += (totalCost - storePromote.getCost())
								/ storePromote.getAnalogyCost() * storePromote.getAnalogyBack();
					}
					totalCost -= promoteBack;

				} // 满赠
				else if (storePromote.getType().intValue() == StorePromoteType.GIFT.ordinal()) {
					
					Iterator<StoreGift> gifts = storePromote.getStoreGifts().iterator();
					while (gifts.hasNext()) {
						
						StoreGift gift = gifts.next();
						OrderGoods og = mkOrderGoodsForFree(gift.getStoreGoods(), gift.getAmount(),
								newOrder);
						
						// 加入到订单商品列表中
						if (null != og) {
							nogList.add(og);
						}
						
					}
					
				}
			}

			// 计算积分
			Integer integral = MyUtil.integral(totalCost);

			// 生成订单记录

			newOrder.setAddress(address.getRegionName() + address.getStreet());
			newOrder.setAddressId(addressId);
			newOrder.setConsignee(address.getConsignee());
			newOrder.setDelivery(deliveryMethod.getName());
			newOrder.setDeliveryId(deliveryMethod.getCatId());
			newOrder.setIntegral(integral);
			newOrder.setIsLocalSale(false);
			newOrder.setIsMemberDel(false);
			newOrder.setIsStoreDel(false);
			newOrder.setMemberByMemberId(member);
			newOrder.setOrderCode("" + 
					MyUtil.makeOrderCode(DateUtil.getTimeStamp())); // TODO 生成订单时生成订单编号
			newOrder.setOrderTime(DateUtil.getTimeStamp());
			newOrder.setPayMethod(null); // TODO 生成订单时记录付款方式
			newOrder.setPay(payType.getName());
			newOrder.setPayId(payType.getCatId());
			newOrder.setPhone(address.getMobile());
			newOrder.setPostalCode(address.getPostalCode());
			newOrder.setPromoteBack(promoteBack);
			newOrder.setPromoteId(storePromote.getPromoteId());
			newOrder.setPromoteName(storePromote.getName());
			newOrder.setPromoteType(null != storePromote.getType() ? storePromote.getType() : null);
			newOrder.setRealCost(totalCost);
			newOrder.setReckonCost(totalCost);
			newOrder.setRemark(orderFromForm.getRemark());
			newOrder.setStatus(OrderStatus.NEW.ordinal());
			newOrder.setStore(store);
			ValueFactory.validate(newOrder);
			newOrder.setOrderId(null);
			orderDao.persist(newOrder);

			// 生成订单商品记录
			for (OrderGoods newOrderGoods : nogList) {
				ValueFactory.validate(newOrderGoods);
				newOrderGoods.setOrderGoodsId(null);
				orderGoodsDao.persist(newOrderGoods);
			}

			// 删除购物车物品
			shoppingDao.deleteByIds(member.getMemberId(), shoppingIds);

		}

		// 通知店铺有新订单
		Store store = null;
		for (Long storeId : storeIdList) {
			store = storeDao.get(storeId);
			store.setIsNewOrder(true);
			storeDao.merge(store);
		}
		
		// 删除用户空的购物车
		shoppingCartDao.deleteEmptyByMemberId(member.getMemberId());

	}
	
	@Override
	public Order addByStore(Store store, Member checker, long saleId, List<LocalSaleGoods> ogs, 
			Float pay, Float change) throws MyException {
		log.debug("addByStore：storeId={},checkerId={},saleId={},count={},pay={},change={}", 
				new Object[]{store.getStoreId(),checker.getMemberId(), saleId, ogs.size(), pay, change});
		
		final String NONE = "-";
		
		OrderPayMethodType pmt = OrderPayMethodType.CASH;
		Float shouldPay = 0f;// 应付金额
		
		if (null == pay) {
			pmt = OrderPayMethodType.COMPANY_ACCOUNT;
		} else {
			shouldPay = pay;
			if (null != change) {
				shouldPay = pay - change;
			}
		}
		
		// 参数检查
		LocalSale sale = localSaleDao.get(saleId);
		if (null == sale || null == ogs || ogs.size() == 0 || null == pmt) {
			throw new MyIllegalArgumentException();
		}
		if (!sale.getStore().equals(store)) {
			throw new MyNoPermissionException();
		}
		
		// 跟订单挂勾的用户
		Member member = sale.getMember();
		// 没指定用户却想从用户的企业账户中扣钱,失败!
		if (null == member && pmt == OrderPayMethodType.COMPANY_ACCOUNT) {
			throw new MyIllegalArgumentException();
		}
		
		// 生成订单
		Order newOrder = new Order();
		// 订单商品集合
		List<OrderGoods> nogList = new ArrayList<OrderGoods>();// newOrderGoodsList
		// 订单金额
		float totalCost = 0;
		// 返现金额
		Float promoteBack = null;
		
		for (LocalSaleGoods og : ogs) {
			
			StoreGoods sg = og.getStoreGoods();
			if (null == sg || null == sg.getStoreGoodsId()) {
				throw new MyIllegalArgumentException();
			}
			sg = storeGoodsDao.get(sg.getStoreGoodsId());
			if (null == sg) {
				throw new MyEntityNotExistsException();
			}
			// TODO 库存不足
			if (sg.getStock() < og.getAmount()) {
				// throw new MxzStoreGoodsException(Code.ERR_10002, sg);
			}
			
			// 订单价格统计
			totalCost += og.getCost();
			
			// 生成订单商品
			OrderGoods nog = new OrderGoods();// newOrderGoods
			nog.setBarCode(sg.getBarCode());
			nog.setBuyCount(og.getAmount());
			nog.setBuyUnit(sg.getUnit());// 购买单位与计费单位一样
			nog.setChecked(true);
			nog.setGoodsTime(sg.getUpdateTime());
			nog.setName(sg.getName());
			nog.setOrder(newOrder);
			nog.setOrderTime(DateUtil.getTimeStamp());
			nog.setPic(sg.getPic());
			nog.setPrice(sg.getPrice());
			nog.setRealCost(og.getCost());
			nog.setRealCount(og.getAmount());
			nog.setReckonCost(og.getCost());
			nog.setReckonCount(og.getAmount());
			nog.setStoreGoodsId(sg.getStoreGoodsId());
			nog.setType(og.getType());
			nog.setUnit(sg.getUnit());
			nog.setUnitConvert(sg.getUnitConvert());
			
			nogList.add(nog);
			
			// 记录出售量
			sale(sg, og.getAmount());
			
		}
		
		// 从用户的企业账户中扣钱
		if (pmt == OrderPayMethodType.COMPANY_ACCOUNT) {
			Company company = store.getCompany();
			MemberVipId id = new MemberVipId();
			id.setCompanyId(company.getCompanyId());
			id.setMemberId(member.getMemberId());
			MemberVip vip = memberVipDao.get(id);
			if (null == vip || vip.getBalance() < totalCost) {
				throw new MyNoPermissionException("余额不足");
			}
			vip.setBalance(vip.getBalance() - totalCost);
			vip.setUpdateTime(DateUtil.getTimeStamp());
			memberVipDao.merge(vip);
		} else if (pmt == OrderPayMethodType.CASH) {
			promoteBack = totalCost - shouldPay;
		}
		
		// 计算积分
		Integer integral = MyUtil.integral(totalCost);

		// 生成订单记录
		newOrder.setAddress(NONE);
		newOrder.setAddressId(null);
		newOrder.setMemberByCheckerId(checker);
		newOrder.setConsignee(NONE);
		newOrder.setDelivery("现场购买");
		newOrder.setDeliveryId(null);
		newOrder.setIntegral(integral);
		newOrder.setIsLocalSale(true);
		newOrder.setIsMemberDel(false);
		newOrder.setIsStoreDel(false);
		newOrder.setMemberByMemberId(member);
		newOrder.setOrderCode("" + 
				MyUtil.makeOrderCode(DateUtil.getTimeStamp())); // TODO 生成订单时生成订单编号
		newOrder.setOrderTime(DateUtil.getTimeStamp());
		newOrder.setPayMethod(pmt.getText()); // TODO 生成订单时记录付款方式
		newOrder.setPayMethodType(pmt.ordinal());
		newOrder.setPay(NONE);
		newOrder.setPayId(null);
		newOrder.setPhone(NONE);
		newOrder.setPostalCode(NONE);
		newOrder.setRealCost(totalCost);
		newOrder.setReckonCost(totalCost);
		newOrder.setPromoteBack(promoteBack);
		newOrder.setSerialCode(sale.getSerialCode());
		newOrder.setStatus(OrderStatus.SUCCESS.ordinal());// TODO
		newOrder.setStore(store);
		ValueFactory.validate(newOrder);
		newOrder.setOrderId(null);
		orderDao.persist(newOrder);

		// 生成订单商品记录
		for (OrderGoods newOrderGoods : nogList) {
			ValueFactory.validate(newOrderGoods);
			newOrderGoods.setOrderGoodsId(null);
			orderGoodsDao.persist(newOrderGoods);
		}	
		
		// 消费记录
		MemberSpend ms = memberSpendDao.get(newOrder.getSerialCode());
		if (null != ms) { 
			if (null == newOrder.getMemberByMemberId()) {
				ms.setIsChecked(true);
				ms.setSpend(newOrder.getRealCost());
				memberSpendDao.merge(ms);
				newOrder.setMemberByMemberId(ms.getMember());
				orderDao.merge(newOrder);
			} else if (ms.getMember().equals(newOrder.getMemberByMemberId())) {
				ms.setIsChecked(true);
				ms.setSpend(newOrder.getRealCost());
				memberSpendDao.merge(ms);
			}
		}
		
		
		// TODO 系统本身有限制每个店铺允许挂起单数（比较少），所以允许通过此遍历方式删除售单物品
		Iterator<LocalSaleGoods> it = sale.getLocalSaleGoodses().iterator();
		while (it.hasNext()) {
			localSaleGoodsDao.delete(it.next());
		}
		// 删除出售单
		localSaleDao.delete(sale);
		
		// 可挂订单数
		store.setPutupRemain(store.getPutupRemain() + 1);
		storeDao.merge(store);
		
		return newOrder;
	}
	

	@Override
	public void addByStoreForSync(Store store, LocalSales4Sync list) throws MyException {
		log.debug("addByStoreForSync：storeId={}", store.getStoreId());
		if (null == list || null == list.getLocalSales() || list.getLocalSales().size() == 0) {
			throw new MyIllegalArgumentException();
		}
		final String NONE = "-";
		// 销售单
		List<LocalSale4Sync> osList = list.getLocalSales();
		for (LocalSale4Sync os : osList) {
			
			// 营业员(用户)
			if (null == os.getCheckerId()) {
				throw new MyIllegalArgumentException();
			}
			StoreMemberId smi = new StoreMemberId();
			smi.setMemberId(os.getCheckerId());
			smi.setStoreId(store.getStoreId());
			StoreMember sm = storeMemberDao.get(smi);
			if (null == sm) {
				throw new MyEntityNotExistsException();
			}
			Member checker = sm.getMember();
			
			// 生成订单
			Order newOrder = new Order();
			// 订单商品集合
			List<OrderGoods> nogList = new ArrayList<OrderGoods>();// newOrderGoodsList
			// 订单金额
			float totalCost = 0;
			
			// 商品
			List<LocalSaleGoods4Sync> ogList = os.getLocalSaleGoodses();
			if (null == ogList || ogList.size() == 0) {
				throw new MyIllegalArgumentException("销售单中至少要有一个销售商品");
			}
			
			for (LocalSaleGoods4Sync og : ogList) {
				
				Long storeGoodsId = og.getStoreGoodsId();
				if (null == storeGoodsId || null == og.getAmount() || null == og.getCost()) {
					throw new MyIllegalArgumentException();
				}
				StoreGoods sg = storeGoodsDao.get(storeGoodsId);
				if (null == sg) {
					throw new MyEntityNotExistsException();
				}
				if (!sg.getStore().equals(store)) {
					throw new MyNoPermissionException();
				}
				
				// 订单价格统计
				totalCost += og.getCost();
				
				// 生成订单商品
				OrderGoods nog = new OrderGoods();// newOrderGoods
				nog.setBarCode(sg.getBarCode());
				nog.setBuyCount(og.getAmount());
				nog.setBuyUnit(sg.getUnit());// 购买单位与计费单位一样
				nog.setChecked(true);
				nog.setGoodsTime(sg.getUpdateTime());
				nog.setName(sg.getName());
				nog.setOrder(newOrder);
				nog.setOrderTime(os.getAddTime());
				nog.setPic(sg.getPic());
				nog.setPrice(sg.getPrice());
				nog.setRealCost(og.getCost());
				nog.setRealCount(og.getAmount());
				nog.setReckonCost(og.getCost());
				nog.setReckonCount(og.getAmount());
				nog.setStoreGoodsId(sg.getStoreGoodsId());
				nog.setType(OrderGoodsType.SELL.ordinal());
				nog.setUnit(sg.getUnit());
				nog.setUnitConvert(sg.getUnitConvert());
				
				nogList.add(nog);
				
				// 记录出售量
				sale(sg, og.getAmount());
			}
			
			// 计算积分
			Integer integral = MyUtil.integral(totalCost);

			// 生成订单记录
			newOrder.setSerialCode(os.getSerialCode());
			newOrder.setAddress(NONE);
			newOrder.setAddressId(null);
			newOrder.setMemberByCheckerId(checker);
			newOrder.setConsignee(NONE);
			newOrder.setDelivery("现场购买");
			newOrder.setDeliveryId(null);
			newOrder.setIntegral(integral);
			newOrder.setIsLocalSale(true);
			newOrder.setIsMemberDel(false);
			newOrder.setIsStoreDel(false);
			newOrder.setMemberByMemberId(null);
			newOrder.setOrderCode("" + 
					MyUtil.makeOrderCode(DateUtil.getTimeStamp())); // TODO 生成订单时生成订单编号
			newOrder.setOrderTime(os.getAddTime());
			newOrder.setPayMethod(OrderPayMethodType.CASH.getText());
			newOrder.setPayMethodType(OrderPayMethodType.CASH.ordinal());
			newOrder.setPay("线下支付");
			newOrder.setPayId(null);
			newOrder.setPhone(NONE);
			newOrder.setPostalCode(NONE);
			newOrder.setRealCost(totalCost);
			newOrder.setReckonCost(totalCost);
			newOrder.setStatus(OrderStatus.SUCCESS.ordinal());// TODO
			newOrder.setStore(store);
			ValueFactory.validate(newOrder);
			newOrder.setOrderId(null);
			orderDao.persist(newOrder);

			// 生成订单商品记录
			for (OrderGoods newOrderGoods : nogList) {
				ValueFactory.validate(newOrderGoods);
				newOrderGoods.setOrderGoodsId(null);
				orderGoodsDao.persist(newOrderGoods);
			}	
			
			// 消费记录
			MemberSpend ms = memberSpendDao.get(newOrder.getSerialCode());
			if (null != ms) {
				ms.setIsChecked(true);
				ms.setSpend(newOrder.getRealCost());
				memberSpendDao.merge(ms);
			}
		}
	}
	
	/**
	 * 商品出售量
	 * @param sg 商品
	 * @param amount 出售量（计费单位）
	 */
	private void sale(StoreGoods sg, float amount) {
		// 售出数量统计（取整）
		int count = new Float(amount).intValue();
		
		/* 更新商品 */
		
		// 周销量
		sg.setDealWeek(sg.getDealWeek() + count);
		// 月销量
		sg.setDealMonth(sg.getDealMonth() + count);
		// 总销量
		sg.setDealAll(sg.getDealAll() + count);
		
		// 减库存
		sg.setStock(MyUtil.numRoundDown(sg.getStock() - amount, 2).floatValue());
		// 折算库存
		if (null != sg.getSellUnit() && sg.getUnitConvert() != 0) {
			sg.setStockConvert(MyUtil.numRoundDown(sg.getStock() / sg.getUnitConvert(), 0).floatValue());// 取整
		} else {
			sg.setStockConvert(MyUtil.numRoundDown(sg.getStock(), 2).floatValue());
		}
		storeGoodsDao.merge(sg);
	}

	/**
	 * 创建订单商品（赠品）
	 * 
	 * @param storeGoods
	 *            商品
	 * @param amount
	 *            赠送数量
	 * @param order
	 *            归属订单
	 * @return
	 */
	private OrderGoods mkOrderGoodsForFree(StoreGoods storeGoods, float amount, Order order) {

		// 计费单位与出售单位是否相同
		boolean isSingleUnit = null == storeGoods.getSellUnit();

		// 库存不足则不送
		if (storeGoods.getStockConvert() < amount) {
			return null;
		}
		
		// 转换成计费单位下的购买量
		float reckonCount = new Double(amount * (isSingleUnit ? storeGoods.getUnitConvert() : 1))
				.floatValue();

		// 订单商品信息
		OrderGoods orderGoods = new OrderGoods();
		orderGoods.setBarCode(storeGoods.getBarCode());
		orderGoods.setBuyCount(amount);// ...
		orderGoods.setBuyUnit(storeGoods.getSellUnit());
		orderGoods.setChecked(isSingleUnit);
		orderGoods.setGoodsTime(storeGoods.getUpdateTime());
		orderGoods.setName(storeGoods.getName());
		orderGoods.setOrder(order);
		orderGoods.setOrderTime(DateUtil.getTimeStamp());
		orderGoods.setPic(storeGoods.getPic());
		orderGoods.setPrice(storeGoods.getPrice());
		orderGoods.setRealCost(0f);
		orderGoods.setRealCount(reckonCount);// ...
		orderGoods.setReckonCost(0f);
		orderGoods.setReckonCount(reckonCount);// ...
		orderGoods.setStoreGoodsId(storeGoods.getStoreGoodsId());
		orderGoods.setType(OrderGoodsType.FREE.ordinal());
		orderGoods.setUnit(storeGoods.getUnit());
		orderGoods.setUnitConvert(storeGoods.getUnitConvert());

		/* 更新商品库存 */
		
		// 减库存
		storeGoods.setStock(MyUtil.numRoundDown(storeGoods.getStock() - reckonCount, 2).floatValue());// ...
		// 计费库存转换为出售出库
		if (null != storeGoods.getSellUnit() && storeGoods.getUnitConvert() != 0) {
			storeGoods.setStockConvert(MyUtil.numRoundDown(storeGoods.getStock()/storeGoods.getUnitConvert(), 0).floatValue());// 取整
		} else {
			storeGoods.setStockConvert(MyUtil.numRoundDown(storeGoods.getStock(), 2).floatValue());
		}
		storeGoodsDao.merge(storeGoods);
		
		return orderGoods;
	}

}
